#pragma once
#include <map>
#include <mutex>

#include <evpp/duration.h>
#include <evpp/event_loop.h>
#include <evpp/buffer.h>
#include <evpp/tcp_callbacks.h>
#include <evpp/tcp_conn.h>
#include <evpp/tcp_server.h>


class MainServer {
public:
    typedef std::function<void()> ServerDoneCallback;

    MainServer(evpp::EventLoop* loop, const std::string& listenAddr, int thread_num);
    ~MainServer();

    bool Start();
    bool Stop();

    bool IsRuning() const;

    void SetDoneCallback(ServerDoneCallback cb) {
        done_callback_ = cb;
    }
protected:
    
    void onConnected(const evpp::TCPConnPtr& conn);
    void onDisconnected(const evpp::TCPConnPtr& conn);

    void onMessage(const evpp::TCPConnPtr& conn, evpp::Buffer* buf);

    void onWriteComplete(const evpp::TCPConnPtr& conn);

    void onServerDone();
private:
    evpp::EventLoop* loop_;
    int thread_num_;
    evpp::TCPServer* server_;
    std::string listen_addr_;

    void AddClient(const evpp::TCPConnPtr& conn);
    void RemoveClient(const evpp::TCPConnPtr& conn);

    std::mutex lock_;
    std::map<uint64_t, evpp::TCPConnPtr> clients_;
    ServerDoneCallback done_callback_;
};

